package com.robot.topology.graph.service;

import java.util.ArrayList;
import java.util.List;

import com.robot.topology.graph.domain.Edge;
import com.robot.topology.graph.domain.Graph;
import com.robot.topology.graph.domain.RoutineTable;
import com.robot.topology.graph.domain.Vertex;
import com.robot.topology.tools.GraphTools;

public class GraphManager {
	private Graph graph;
	private Double initialWeightEdge;

	public GraphManager(Graph graph) {
		this.graph=graph;		
	}

	public List<Edge> getOutEdgesForVertex(Vertex vertex){
		ArrayList<Edge> listOfEdge = new ArrayList<Edge>();

		for (Edge currentEdge : graph.getEdges()){
			if (currentEdge.getSource().equals(vertex)){
				listOfEdge.add(currentEdge);
				System.out.println(currentEdge.toStringWeight());
			}
		}

		return listOfEdge;
	}

	//Initialize the weight of the edges, all edges at the same value
	// Return the value chosen
	public Double initializeWeightEdges(){
		initialWeightEdge= GraphTools.initializeWeightAtRandom();
		for (Edge currentEdge : graph.getEdges()){
			currentEdge.setWeight(initialWeightEdge);
		}
		return initialWeightEdge;
	}


	//Create the routine tables
	public void createRoutineTables (Graph theGraph){
		List<Edge> listOfEdges = new ArrayList<Edge>();
		RoutineTable currentRoutineTable;
		//Create routine table for each Vertex of Graph
		for (Vertex currentVertex : theGraph.getVertexes() ){
			listOfEdges=this.getOutEdgesForVertex(currentVertex);
			currentRoutineTable = new RoutineTable(listOfEdges);
			currentVertex.setRoutineTable(currentRoutineTable);
		}
	}

	//Update the routine tables with the new weights of the edges
	public void updateRoutineTables (Graph theGraph){
		List<Edge> listOfEdges = new ArrayList<Edge>();
		RoutineTable currentRoutineTable;
		//Create routine table for each Vertex of Graph
		for (Vertex currentVertex : theGraph.getVertexes() ){
			listOfEdges=this.getOutEdgesForVertex(currentVertex);
			currentRoutineTable = new RoutineTable(listOfEdges);
			currentVertex.setRoutineTable(currentRoutineTable);
		}
	}
	
	public void displayRoutineTables(Graph theGraph) {
		for (Vertex currentVertex : theGraph.getVertexes())
			System.out.println(currentVertex.toString());
	}

	// Convergence criteria
	public Boolean hasConverged(){
		Boolean hasConverged=false;
		for (Edge currentEdge : graph.getEdges()){
			if (currentEdge.getId()=="C1R3"
					|| currentEdge.getId()=="C1C2"){
				if (currentEdge.getWeight()>=1)
					hasConverged=true;
			}
		}
		return hasConverged;
	}
}
